;Copyright 2000 - Mark McDonald All rights reserved
; DECLARE: FUNCTION intinkey() AS INTEGER
; DESC:    Return keyboard character as an integer.  Returns zero
;          if no key in buffer.
; EXAMP:   Char = intinkey

MCODE Segment Byte
        Assume  CS: MCODE

LastKey DW 0


        Public  intinkey

intinkey Proc   Far
        push    BX                      ;
        push    ES                      ;

        int     28h                     ; give up time slice
        mov     AH,0C0h                 ; get pointer to BIOS data area
        int     15h                     ; call BIOS
        add     BX,5                    ; point BX to equipment byte
        test    Byte Ptr ES: [BX],16    ; see if bit 5 is set
        mov     AH,1                    ; assume 84key keyboard
        jz      CheckBuffer             ; no, it's not an extended keyboard
        add     AH,10h                  ; use extended function
CheckBuffer:
        int     16h                     ; call the BIOS
        mov     AX,0                    ; assume no characters
        jz      Exit                    ; no characters, were done
        test    Byte Ptr ES: [BX],16    ; see if bit 5 is set
        mov     AH,0                    ; assume 84key keyboard
        jz      RemoveKey               ; no, it's not an extended keyboard
        add     AH,10h                  ; use extended function
RemoveKey:
        int     16h                     ; get key from buffer
        cmp     AL,0                    ; is it an extended key?
        jz      ExtKey                  ; yes, go handle it
        test    Byte Ptr ES: [BX],16    ; see if bit 5 is set
        jz      NotExtended             ; no, it's not an extended keyboard
        cmp     AL,224                  ; is it an extended key?
        je      ExtKey                  ; yes, convert it
NotExtended:
        xor     AH,AH                   ; no, zero AH
        jmp     Short Exit              ;
ExtKey:
        or      AH, AH                  ; does scancode = 0
        jz      NotExtended             ; yes, it's not extended
        mov     AL,AH                   ; move the extended code into AL
        xor     AH,AH                   ; zero out AH
        neg     AX                      ; and make the result negative
Exit:
        mov     CS: LastKey, AX         ; save it in LastKey
        pop     ES                      ;
        pop     BX                      ;
        retf                            ;
intinkey EndP

; DECLARE: FUNCTION intwaitkey() AS INTEGER
; DESC:    Return keyboard character as an integer.  Waits until a key
;          is pressed.
; EXAMP:   Char = intwaitkey

        Public  intwaitkey

intwaitkey Proc   Far
        push    BX                      ;
        push    ES                      ;
WaitLoop:
        int     28h                     ; give up time slice
        mov     AH,0C0h                 ; get pointer to BIOS data area
        int     15h                     ; call BIOS
        add     BX,5                    ; add 5 to BX
        test    Byte Ptr ES: [BX],16    ; see if bit 5 is set
        mov     AH,1                    ; assume 84key keyboard
        jz      CheckKBuffer            ; no, it's not an extended keyboard
        add     AH,10h                  ; use extended function
CheckKBuffer:
        int     16h                     ; call the BIOS
        mov     AX,0                    ; assume no characters
        jz      WaitLoop                ; no characters, keep looping
        test    Byte Ptr ES: [BX],16    ; see if bit 5 is set
        mov     AH,0                    ; assume 84key keyboard
        jz      Remove_Key              ; no, it's not an extended keyboard
        add     AH,10h                  ; use extended function
Remove_Key:
        int     16h                     ; get key from buffer
        cmp     AL,0                    ; is it an extended key?
        jz      ExtKey                  ; yes, go handle it
        test    Byte Ptr ES: [BX],16    ; see if bit 5 is set
        jz      Not_Extended            ; no, it's not an extended keyboard
        cmp     AL,224                  ; is it an extended key?
        je      Ext_Key                 ; yes, convert it
Not_Extended:
        xor     AH,AH                   ; no, zero AH
        jmp     Short Wait_Exit         ;
Ext_Key:
        mov     AL,AH                   ; move the extended code into AL
        xor     AH,AH                   ; zero out AH
        neg     AX                      ; and make the result negative
Wait_Exit:
        mov     CS: LastKey, AX         ; save it in LastKey
        pop     ES                      ;
        pop     BX                      ;
        retf                            ;
intwaitkey EndP

; DECLARE: FUNCTION intgetlastkey() AS INTEGER
; DESC:    Return the key code for the last key removed from the keyboard
;          buffer using intinkey.
; EXAMP:   Char = intgetlastkey

        Public intgetlastkey

intgetlastkey Proc Far
        mov     AX, CS: LastKey         ; put saved code in AX
        retf                            ;
intgetlastkey EndP

; DECLARE: SUB intsetlastkey(BYVAL integer)
; DESC:    Set the value returned in intgetlastkey.
; EXAMP:   intsetlastkey %K.ESC

        Public intsetlastkey

intsetlastkey Proc Far

ARG     NewKey:WORD = Retbytes

        push    BP                      ;
        mov     BP, SP                  ;

        mov     AX, NewKey              ; get new value
        mov     CS: LastKey, AX         ; save it

        pop     BP                      ;
        retf    Retbytes                ;
intsetlastkey EndP
MCODE EndS
        End
